/**
 * 结束该头文件内的宏，可以较方便地定义对各个 flags 变量的操作。
 */
#ifndef _AHAMOLETT_FLAGS_OPERATIONS_H_
#define _AHAMOLETT_FLAGS_OPERATIONS_H_

#include <stdatomic.h>

/**
 * @brief 一个方便定义对flags内各个比特操作的宏。
 * 
 * 由于对各个 flags 变量内每个 flag 操作都几乎一致，所以定义这个宏用于简化代码。
 * 假设进行操作的类型为Type，这个宏使用一次会定义三个总是内联的函数：
 * -    TypeXXX(page)       检查 type 的某个标志知否置位。
 * -    SetTypeXXX(page)    将 type 的某个标志位置位，并返回这个标志操作前的置位状态。
 * -    ClearTypeXXX(page)  将 type 的某个标志位清除，请返回这个标志操作前的置位状态。
 * 
 * 所有操作返回 true 都代表对应标志被（或曾经被）置位，返回 false 都代表对应标志被（或曾经被）
 * 清除。
 * 
 * @param type flags 状态字所在结构体类型。
 * @param member flags 状态字在结构体内的成员名。
 * @param type_name 整组操作的名称。
 * @param name 对标志位操作的名称。
 * @param bit 标志位所在的位号。
 */
#define DEFINE_FLAG_BIT(type, member, type_name, name, bit)    \
static inline int type_name##name(type *ptr)    \
{   \
    return !!(atomic_load(&ptr->member) & (1UL << (bit)));  \
}   \
static inline int Set##type_name##name(type *ptr)   \
{   \
    typeof(ptr->member) old_flags = \
        atomic_fetch_or(&ptr->member, 1UL << (bit));    \
    return !!(old_flags & (1UL << (bit)));  \
}   \
static inline int Clear##type_name##name(type *ptr) \
{   \
    typeof(ptr->member) old_flags = \
        atomic_fetch_and(&ptr->member, ~(1UL << (bit)));    \
    return !!(old_flags & (1UL << (bit)));  \
}

#endif
